package com.yy.dao.db;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;

import com.yy.dao.annotation.DbField;
import com.yy.dao.annotation.DbTable;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * User: gongyongfeng2@yy.com
 * Date: 2020/7/2 18 :21
 */
class BaseDao<T> implements IBaseDao<T> {
    private SQLiteDatabase mSQLiteDatabase;
    private String tableName;
    private Class<T> entityClass;
    private Map<String, Field> cacheField;
    private boolean isInit = false;

    public void init(SQLiteDatabase sqLiteDatabase, Class<T> entityClass) {
        mSQLiteDatabase = sqLiteDatabase;
        this.entityClass = entityClass;
        if (!isInit) {
            if (entityClass.getAnnotation(DbTable.class) == null) {
                this.tableName = entityClass.getSimpleName();
            } else {
                this.tableName = entityClass.getAnnotation(DbTable.class).value();
            }
            String createTableSql = getCreateTableSql();
            mSQLiteDatabase.execSQL(createTableSql);
            cacheField = new HashMap<>();
            initCacheMap();
            isInit = true;
        }
    }

    private void initCacheMap() {
        String sql = "select * from " + tableName + " limit 1, 0";
        Cursor cursor = mSQLiteDatabase.rawQuery(sql, null);
        String[] columnNames = cursor.getColumnNames();
        Field[] fields = entityClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
        }

        for (String columnName : columnNames) {
            Field columnField = null;
            for (Field field : fields) {
                String fieldName = "";
                if (field.getAnnotation(DbField.class) != null) {
                    fieldName = field.getAnnotation(DbField.class).value();
                } else {
                    fieldName = field.getName();
                }
                if (columnName.equals(fieldName)) {
                    columnField = field;
                    break;
                }
            }
            if (columnField != null) {
                cacheField.put(columnName, columnField);
            }
        }
    }

    private String getCreateTableSql() {
        //create table if not exists
        // tb_user(_id integer, name varchar(20), password varchar(20),)
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("create table if not exists ");
        stringBuffer.append(tableName + "(");
        //反射得到所有的成员变量
        Field[] declaredFields = entityClass.getDeclaredFields();
        for (Field field : declaredFields) {
            Class type = field.getType();// 拿到成员的类型

            if (field.getAnnotation(DbField.class) != null) {
                //通过注解获取
                if (type == String.class) {
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " TEXT,");
                } else if (type == Integer.class) {
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " INTEGER,");
                } else if (type == Long.class) {
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " BIGINT,");
                } else if (type == Double.class) {
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " DOUBLE,");
                } else if (type == byte[].class) {
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " BLOB,");
                } else {
                    //不支持的类型
                    continue;
                }
            } else {
                //通过反射获取
                if (type == String.class) {
                    stringBuffer.append(field.getName() + " TEXT,");
                } else if (type == Integer.class) {
                    stringBuffer.append(field.getName() + " INTEGER,");
                } else if (type == Long.class) {
                    stringBuffer.append(field.getName() + " BIGINT,");
                } else if (type == Double.class) {
                    stringBuffer.append(field.getName() + " DOUBLE,");
                } else if (type == byte[].class) {
                    stringBuffer.append(field.getName() + " BLOB,");
                } else {
                    //不支持的类型
                    continue;
                }
            }
        }

        if (stringBuffer.charAt(stringBuffer.length() - 1) == ',') {
            stringBuffer.deleteCharAt(stringBuffer.length() - 1);
        }
        stringBuffer.append(")");
        return stringBuffer.toString();
    }

    @Override
    public long insert(T entity) {
        Map<String, String> map = getValues(entity);
        ContentValues values = getContentValues(map);
        mSQLiteDatabase.insert(tableName, null, values);
        return 0;
    }

    private ContentValues getContentValues(Map<String, String> map) {
        ContentValues values = new ContentValues();
        Set<String> keys = map.keySet();
        for (String key : keys) {
            String value = map.get(key);
            if (value != null) {
                values.put(key, value);
            }
        }
        return values;
    }

    private Map<String, String> getValues(T entity) {
        Map<String, String> maps = new HashMap<>();
        Iterator<Field> iterator = cacheField.values().iterator();
        while (iterator.hasNext()) {
            Field field = iterator.next();
            field.setAccessible(true);
            try {
                //获取对象的属性值
                Object object = field.get(entity);
                if (object != null) {
                    String value = object.toString();
                    String key = "";
                    if (field.getAnnotation(DbField.class) != null) {
                        key = field.getAnnotation(DbField.class).value();
                    } else {
                        key = field.getName();
                    }

                    if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
                        maps.put(key, value);
                    }
                }

            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return maps;
    }

    @Override
    public long update(T entity, T where) {

        return 0;
    }

    @Override
    public int delete(T where) {
        return 0;
    }

    @Override
    public List<T> query(T where) {
        return null;
    }

    @Override
    public List<T> query(T where, String orderBy, Integer startId, Integer limit) {
        return null;
    }
}
